﻿using AutoMapper;
using BaseRepository.Redis;
using MediatR;
using PLC.Domain.Entity;
using PLC.Domain.GlobConfig;
using PLC.Domain.Models;

namespace PLC.Domain.Events.Handlers;

public class DeviceDataGroupHandler : INotificationHandler<DeviceDataGroupHandleModel>
{
    private readonly IMapper _mapper;
    private readonly IMediator _mediator;
    private readonly IRedisRepository _redisRepository;

    public DeviceDataGroupHandler(IMediator mediator,
        IRedisRepository redisRepository,
        IMapper mapper)
    {
        _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
        _redisRepository = redisRepository ?? throw new ArgumentNullException(nameof(redisRepository));
        _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
    }

    public async Task Handle(DeviceDataGroupHandleModel notification, CancellationToken cancellationToken)
    {
        // 先处理数据
        // 然后分别执行各自的事件
        var barcodeDataList = new List<BarcodeData>();
        var deviceStatusList = new List<DeviceStatus>();
        var productionDataList = new List<ProductionData>();
        var airtightDataList = new List<AirtightData>();
        var repairAirtightDataList = new List<RepairAirtightData>();
        var pressureDataList = new List<PressureData>();
        var deviceBeatList = new List<DeviceBeat>();
        var yieldRateList = new List<YieldRate>();
        foreach (var plcReadModel in notification.PlcReadModels)
        {
            // 条码数据
            if (plcReadModel.BarcodeDatas.Count > 0)
            {
                barcodeDataList.AddRange(
                    _mapper.Map<List<BarcodeData>>(plcReadModel.BarcodeDatas.Where(p => p.ValidResult).ToList()).Select(p => p.Build()).ToList());
            }
            // 设备状态
            if (plcReadModel.DeviceStatus != null) deviceStatusList.Add(plcReadModel.DeviceStatus);
            // 生产数据
            if (plcReadModel.DtoProductionData != null) productionDataList.Add(_mapper.Map<ProductionData>(plcReadModel.DtoProductionData).Build());
            // 气密数据
            if (plcReadModel.AirtightData != null) airtightDataList.Add(plcReadModel.AirtightData);
            // 维修工站的气密数据
            if (plcReadModel.RepairAirtightData != null) repairAirtightDataList.Add(plcReadModel.RepairAirtightData);
            // 装堆机压力数据
            if (plcReadModel.PressureData != null) pressureDataList.Add(plcReadModel.PressureData);
            // 设备节拍
            if (plcReadModel.DeviceBeat != null) deviceBeatList.Add(plcReadModel.DeviceBeat);
            //设备良品率
            if(plcReadModel.YieldRate!=null) yieldRateList.Add(plcReadModel.YieldRate);
        }


        // 先要比较判断一下数据  因为不是所有的状态都需要存储的 根据redis里存储的状态来判断吧
        // 对于设备状态数据进行了过滤
        var filterDeviceStatusDatas = await FilterDeviceStatus(deviceStatusList);
        // 发送对应的事件
        await _mediator.Publish(new SaveBarcodeDataModel { BarcodeDataList = barcodeDataList }, cancellationToken);
        await _mediator.Publish(new SaveProductionModel { ProductionDataList = productionDataList }, cancellationToken);
        await _mediator.Publish(new SaveDeviceStatusModel { DeviceStatusList = filterDeviceStatusDatas },
            cancellationToken);
        await _mediator.Publish(new SaveAirtightDataModel { AirtightDatas = airtightDataList }, cancellationToken);
        await _mediator.Publish(new SaveRepairAirtightModel { RepairAirtightDatas = repairAirtightDataList },
            cancellationToken);
        await _mediator.Publish(new SavePressureDataModel { PressureDatas = pressureDataList }, cancellationToken);
        // 发送数据的事件
        await _mediator.Publish(new SendDataModel
            {
                DeviceStatusList = deviceStatusList,
                DtoProductionDatas = notification.PlcReadModels.Select(p=>p.DtoProductionData).Where(p=>p!=null).ToList(),
                DeviceBeatList = deviceBeatList,
                DeviceYieldRateList = yieldRateList
            },
            cancellationToken);
    }

    /// <summary>
    ///     校验数据状态的数据
    /// </summary>
    /// <param name="deviceStatusList"></param>
    /// <returns></returns>
    private async Task<List<DeviceStatus>> FilterDeviceStatus(List<DeviceStatus> deviceStatusList)
    {
        var dataList = await _redisRepository.StringGet<List<DeviceStatus>>(RedisKey.DeviceStatus);
        if (dataList == null)
        {
            await _redisRepository.StringSet(RedisKey.DeviceStatus, deviceStatusList);
            return deviceStatusList;
        }

        // 如果存在  那么就要校验对应的数据是否相同了
        var result = new List<DeviceStatus>();
        foreach (var deviceStatus in deviceStatusList)
        {
            // 如果redis中没有  那么就要加入
            var data = dataList.FirstOrDefault(p => p.DeviceId == deviceStatus.DeviceId);
            if (data == null)
            {
                result.Add(deviceStatus);
                dataList.Add(deviceStatus);
                continue;
            }

            // 判断有没有修改
            if (deviceStatus.RegisterValue != data.RegisterValue)
            {
                result.Add(deviceStatus);
                dataList.RemoveAll(p => p.DeviceId == deviceStatus.DeviceId);
                dataList.Add(deviceStatus);
            }
        }

        // 如果有修改的数据 那么就要更新redis了
        if (result.Count > 0) await _redisRepository.StringSet(RedisKey.DeviceStatus, dataList);
        return result;
    }
}